﻿#include <iostream>
#include <boost/asio.hpp>
#include <set>
#include <thread>
#include <memory>

const int max_length = 1024;
using socket_ptr = std::shared_ptr<boost::asio::ip::tcp::socket>;
std::set<std::shared_ptr<std::thread>>thread_set;

void session(socket_ptr sock)//处理已连接客户端的数据收发
{
	try
	{
		while (true)
		{
			char data[max_length];
			memset(data, '\0', max_length);
			boost::system::error_code error;
			size_t length = sock->read_some(boost::asio::buffer(data, max_length), error);
			if (error == boost::asio::error::eof)//对端关闭
			{
				std::cout << "connection close by peer" << std::endl;
				break;
			}
			else if (error)
			{
				throw boost::system::system_error(error);
			}
			//打印收到的数据
			std::cout << "receive from " << sock->remote_endpoint().address().to_string() << std::endl;
			std::cout << "receive message is " << data << std::endl;
			//将收到的数据回传给对方
			boost::asio::write(*sock, boost::asio::buffer(data, length));
		}
	}
	catch (const std::exception& e)
	{
		std::cout << e.what() << std::endl;
	}
}

void server(boost::asio::io_context& ioc, unsigned short port)
{
	boost::asio::ip::tcp::acceptor accept(ioc, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port));
	while (true)
	{
		socket_ptr socket(new boost::asio::ip::tcp::socket(ioc));
		accept.accept(*socket);
		auto t = std::make_shared<std::thread>(session, socket);
		thread_set.insert(t);
	}
}

int main()
{
	try
	{
		boost::asio::io_context ioc;
		server(ioc, 8888);
		for (auto& t : thread_set)
		{
			t->join();
		}
	}
	catch (const std::exception& e)
	{
		std::cerr << "Exception:" << e.what() << std::endl;
	}
    return 0;
}
